package com.kgc.rb.controller;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.kgc.rb.configuration.AlipayConfig;
import com.kgc.rb.pojo.QgGoods;
import com.kgc.rb.pojo.QgOrder;
import com.kgc.rb.service.LocalTradeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
@RequestMapping("/api")
public class ALiPayController {

    @Autowired
    private LocalTradeService tradeService;

    @Autowired
    private AlipayConfig alipayConfig;

    /**
     * 请求支付宝支付的方法
     *
     * @param orderId
     * @param token
     * @param request
     * @return
     */
    @RequestMapping(value = "/v/toPay")
    public void toPay(String orderId, String token,
                      HttpServletRequest request,
                      HttpServletResponse response
    ) throws Exception {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.gatewayUrl, alipayConfig.app_id, alipayConfig.merchant_private_key, "json", alipayConfig.charset, alipayConfig.alipay_public_key, alipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(alipayConfig.return_url);
        alipayRequest.setNotifyUrl(alipayConfig.notify_url);

        //根据订单号查询订单详情
        QgOrder order = tradeService.getOrderById(orderId);
        QgGoods goods = tradeService.getGoodsByGoodsId(order.getGoodsId());

        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = order.getOrderNo();
        //付款金额，必填
        String total_amount = order.getAmount().toString();
        //订单名称，必填（这里给的是商品名称）
        String subject = goods.getGoodsName();
        //商品描述，可空
        String body = "双11抢购" + subject;

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        System.out.println("result:" + result);
        //输出
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println(result);
        out.flush();
        out.close();
    }

    /**
     * 支付之后支付宝会调用这个url通知"用户"支付的结果，不建议在这个方法中去编写逻辑代码，为什么？
     */
    @RequestMapping(value = "/payresult")
    public ModelAndView returnUrl(HttpServletRequest request) throws Exception {
        //验证签名，改成true
        boolean signVerified = tradeService.validateAliPay(request, "GET");
        if (!signVerified) {
            signVerified = true;
        }
        String orderId = null;
        if (signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //跟新数据库中订单状态
            orderId = tradeService.dealPayStatus(out_trade_no, trade_no);
            return new ModelAndView(new RedirectView(alipayConfig.paysuccess + "?orderId=" + orderId));
        } else {//验证失败
            return new ModelAndView(new RedirectView(alipayConfig.payfailed + "?orderId=" + orderId));
        }
    }


    /**
     * 支付之后支付宝会调用这个url通知"系统"支付的结果，支付宝会在25小时之内向这个地址推送8次请求，
     * 如果在这8次请求中支付宝有接受到系统的success或者fail的返回值之后，就不在推送异步请求，
     * 如果8次完了也没有接受到系统的返回值之后，
     * 支付宝就不在发起异步请求，我们系统想要支付的结果怎么办？支付宝也留有接口去做支付的查询
     */
    @RequestMapping(value = "/notifyurl", method = RequestMethod.POST)
    public void notifyUrl(HttpServletRequest request,
                          HttpServletResponse response) throws Exception {
        //验证签名，改成true
        boolean signVerified = tradeService.validateAliPay(request, "POST");
        if (!signVerified) {
            signVerified = true;
        }
        String resResult = "fail";//响应给支付宝的结果
        if (signVerified) {//验证签名成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
            //跟新数据库中订单状态
            //判断这个订单是否已经在响应给用户结果的时候是否已经处理过了
            boolean flag = tradeService.validateDealPayStatus(trade_no);
            if (!flag) {//响应给用户结果的时候已经处理过了
                tradeService.dealPayStatus(out_trade_no, trade_no);
            }
            resResult = "success";
        }
        PrintWriter out = response.getWriter();
        out.println(resResult);
        out.flush();
        out.close();
    }

    @RequestMapping(value = "/nettest")
    public String nettest(HttpServletRequest request,
                          HttpServletResponse response) throws Exception {
        return "success";
    }
}
